package com.winbomb.kingcard.framework.impl;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.view.Window;
import android.view.WindowManager;

import com.winbomb.kingcard.framework.Audio;
import com.winbomb.kingcard.framework.FileIO;
import com.winbomb.kingcard.framework.Game;
import com.winbomb.kingcard.framework.Graphics;
import com.winbomb.kingcard.framework.Input;
import com.winbomb.kingcard.framework.Screen;

public abstract class AndroidGame extends Activity implements Game {

	/** 剪切渲染模式：保持纵横比，x或y轴多出的区域不进行渲染 */
	public static final int CLIP_RENDER = 0;

	/** 拉伸渲染模式： 不保持纵横比，将图像拉伸铺满x和y轴 */
	public static final int SCALE_RENDER = 1;

	public AndroidFastRenderView renderView;
	Graphics graphics;
	Audio audio;
	Input input;
	FileIO fileIO;
	Screen screen;
	WakeLock wakeLock;

	/** 渲染模式 ,默认为剪切渲染模式 */
	int renderType = CLIP_RENDER;
	/** 缓冲图像的宽度 */
	int frameBufferWidth = 480;
	/** 缓冲图像的高度 */
	int frameBufferHeight = 320;
	/** 手机屏幕的宽度 */
	int screenWidth;
	/** 手机屏幕的高度 */
	int screenHeight;
	/** X轴的伸缩比,在剪切模式下，scaleX应与scaleY一致 */
	float scaleX;
	/** Y轴的伸缩比,在剪切模式下，scaleX应与scaleY一致 */
	float scaleY;
	/** X轴的剪切量，只对剪切渲染模式有效 */
	int offsetX;
	/** Y轴的剪切量，只对剪切渲染模式有效 */
	int offsetY;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// boolean isLandscape = getResources().getConfiguration().orientation
		// == Configuration.ORIENTATION_LANDSCAPE;
		Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth, frameBufferHeight, Config.RGB_565);

		screenWidth = getWindowManager().getDefaultDisplay().getWidth();
		screenHeight = getWindowManager().getDefaultDisplay().getHeight();

		scaleX = (float) screenWidth / frameBufferWidth;
		scaleY = (float) screenHeight / frameBufferHeight;

		// 如果是剪切渲染模式，需要计算offsetX和offsetY
		if (renderType == CLIP_RENDER) {

			if (scaleX <= scaleY) {
				scaleY = scaleX;
				offsetX = 0;
				offsetY = (int) ((screenHeight - frameBufferHeight * scaleY) / 2);
			} else {
				scaleX = scaleY;
				offsetY = 0;
				offsetX = (int) ((screenWidth - frameBufferWidth * scaleX) / 2);
			}
		}

		renderView = new AndroidFastRenderView(this, frameBuffer);
		graphics = new AndroidGraphics(getAssets(), frameBuffer);
		fileIO = new AndroidFileIO(getAssets());
		audio = new AndroidAudio(this);
		input = new AndroidInput(this, renderView);
		screen = getStartScreen();
		setContentView(renderView);

		PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
		wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");
	}

	@Override
	public void onResume() {
		super.onResume();
		wakeLock.acquire();
		screen.resume();
		renderView.resume();
	}

	@Override
	public void onPause() {
		super.onPause();
		wakeLock.release();
		renderView.pause();
		screen.pause();

		if (isFinishing())
			screen.dispose();
	}

	@Override
	public Input getInput() {
		return input;
	}

	@Override
	public FileIO getFileIO() {
		return fileIO;
	}

	@Override
	public Graphics getGraphics() {
		return graphics;
	}

	@Override
	public Audio getAudio() {
		return audio;
	}

	@Override
	public void setScreen(Screen screen) {
		if (screen == null)
			throw new IllegalArgumentException("Screen must not be null");

		this.screen.pause();
		this.screen.dispose();
		screen.resume();
		screen.update(0);
		this.screen = screen;
	}

	public Screen getCurrentScreen() {
		return screen;
	}

	public int getScreenWidth() {
		return this.screenWidth;
	}

	public int getScreenHeight() {
		return this.screenHeight;
	}

	public int getRenderType() {
		return renderType;
	}

	public float getScaleX() {
		return scaleX;
	}

	public float getScaleY() {
		return scaleY;
	}

	public int getOffsetX() {
		return offsetX;
	}

	public int getOffsetY() {
		return offsetY;
	}
}